/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package com.plian.system.service.fr.bank.impl;

import com.plian.Tools.BigDecimalUtil;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.system.constant.baseinfo.ValueSetConstant;
import com.plian.system.entity.fr.bank.BankAccountInfo;
import com.plian.system.mapper.fr.bank.BankAccountInfoMapper;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.service.bt.baseinfo.BaseInfoService;
import com.plian.system.service.fr.bank.IBankAccountInfoService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.vo.fr.bank.BankAccountInfoVO;
import com.plian.system.vo.report.HeaderVO;
import com.plian.system.vo.report.ReportReturnVO;
import com.plian.system.vo.report.ReportVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.math.BigDecimal;
import java.util.*;

/**
 * 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class BankAccountInfoServiceImpl extends BaseServiceImpl<BankAccountInfoMapper, BankAccountInfo> implements IBankAccountInfoService {

	private BaseInfoService baseInfoService;

	private BankAccountInfoMapper bankAccountInfoMapper;

	private OrgzationService orgzationService;

//	@Override TODO DEL
//	@Transactional(rollbackFor=RuntimeException.class)
//	public boolean saveOrUpdate(BankAccountInfo bankAccountInfo) {
//		bankAccountInfo.setFormType(String.valueOf(FormTypeConstant.FR_BANK_ACCOUNT));
//		return super.saveOrUpdate(bankAccountInfo);
//	}
//
//	@Override
//	@Transactional(rollbackFor=RuntimeException.class)
//	public boolean deleteLogic(List<Long> ids) {
//		for (Long id : ids) {
//			BankAccountInfo bankAccountInfo = getById(id);
//			if (bankAccountInfo == null || StringUtil.isNotBlank(bankAccountInfo.getAddType())) {
//				return false;
//			}
//		}
//		return super.deleteLogic(ids);
//	}
//
//	@Override
//	public ReportReturnVO summarySumList(BankAccountInfo bankAccountInfo) {
//		List<BankAccountInfoVO> data = baseMapper.summaryList(bankAccountInfo);
//		ArrayList<PageData> pdlist = new ArrayList<>();
//		if (CollectionUtil.isNotEmpty(data)){
//			HashMap<String, Integer> accountnum = new HashMap<>();
//			HashMap<String, BigDecimal> accountbalence = new HashMap<>();
//			for (int i = 0; i < data.size(); i++){
//				BankAccountInfoVO result = data.get(i);
//				String orgName = result.getOrgName();
//
//				String orgId = result.getOrgId();
//				String topGroupName = result.getTopGroupName();
//				String key = topGroupName + "\t"+orgName +"\t"+orgId;
//				boolean b = accountnum.containsKey(key);
//				if (b){
//					Integer num = accountnum.get(key);
//					accountnum.put(key,num+1);
//					BigDecimal oldblance = accountbalence.get(key);
//					oldblance = BigDecimalUtil.add(oldblance, result.getBalance());
//					accountbalence.put(key,oldblance);
//				}else {
//					accountnum.put(key,1);
//					accountbalence.put(key,result.getBalance());
//				}
//			}
//			Set<String> strings = accountnum.keySet();
//			Iterator<String> iterator = strings.iterator();
//			BigDecimal sumBalance=new BigDecimal(0);
//			Integer sumNum=0;
//			while (iterator.hasNext()){
//				PageData pageData = new PageData();
//				String next = iterator.next();
//				Integer num = accountnum.get(next);
//				BigDecimal balance = accountbalence.get(next);
//				if(balance!=null){
//					sumBalance=sumBalance.add(balance);
//				}
//				sumNum+=num;
//				String[] split = next.split("\t");
//				String topGroupName = split[0];
//				String orgName = split[1];
//				String orgId = split[2];
//				if ("null".equals(orgId) && "null".equals(orgName)){
//
//				}else {
//					pageData.put("orgName",orgName);
//					pageData.put("orgId",orgId);
//					pageData.put("topGroupName",topGroupName);
//					pageData.put("numbers",num);
//					pageData.put("balance",balance);
//					pdlist.add(pageData);
//				}
//			}
//			PageData sumPageData=new PageData();
//			sumPageData.put("orgName","-");
//			sumPageData.put("orgId","00");
//			sumPageData.put("topGroupName","合计");
//			sumPageData.put("numbers",sumNum);
//			sumPageData.put("balance",sumBalance);
//			sumPageData.put("companyNum",pdlist.size());
//			pdlist.add(sumPageData);
//		}
//
//
//		ReportReturnVO reportReturnVO = new ReportReturnVO();
//		ReportVO reportVO = new ReportVO();
//		reportVO
//				.addHeader(HeaderVO.builder().key("topGroupName").title("所属集团").build())
//				.addHeader(HeaderVO.builder().key("orgName").title("公司名称").build())
//				.addHeader(HeaderVO.builder().key("numbers").title("账户数").build())
//				.addHeader(HeaderVO.builder().key("balance").title("余额合计").build());
//		reportVO.setData(pdlist);
//		reportReturnVO.setGrids(reportVO);
//		return reportReturnVO;
//	}

	@Override
	public ReportReturnVO summaryList(BankAccountInfo bankAccountInfo) {

		List<BankAccountInfoVO> data = baseMapper.summaryList(bankAccountInfo);
		List<BankAccountInfoVO> results = new ArrayList<>();
		if (CollectionUtil.isNotEmpty(data)){
			int totalCount = 0;
			BigDecimal totalBalance = new BigDecimal(0);
			int subtotalCount = 0;
			BigDecimal subtotalBalance = new BigDecimal(0);
			String lastTopGroupId = "";
			Map<String, String> currencyMap = baseInfoService.getChildMap(ValueSetConstant.CURRENCY);
			for (int i = 0; i < data.size(); i++){
				BankAccountInfoVO result = data.get(i);
				if (StringUtil.isNotBlank(lastTopGroupId) && !lastTopGroupId.equals(result.getTopGroupId())){
					BankAccountInfoVO subtotal = new BankAccountInfoVO();
					subtotal.setTopGroupName("小计：" + subtotalCount);
					subtotal.setBalance(subtotalBalance);
					results.add(subtotal);
					subtotalCount = 1;
					subtotalBalance = result.getBalance();
				}else {
					subtotalCount++;
					subtotalBalance = BigDecimalUtil.add(subtotalBalance, result.getBalance());
				}
				lastTopGroupId = result.getTopGroupId();
				totalCount++;
				totalBalance = BigDecimalUtil.add(totalBalance, result.getBalance());
				result.setAccountStatusName(getAccountStatusName(result.getAccountStatus()));
				result.setAccountTypeName(getAccountTypeName(result.getAccountType()));
				result.setAccountUseName(getAccountUseName(result.getAccountUse()));
				result.setCurrentName(currencyMap.get(result.getCurrentCode()));
				if (result.getRateType() != null){
					if (result.getRateType() == 1){
						result.setRateTypeName("基准利率");
					}else if(result.getRateType() == 2){
						result.setRateTypeName("无限额协议利率");
					}else if(result.getRateType() == 3){
						result.setRateTypeName("有限额协议利率");
					}
				}
				results.add(result);
				if (i == data.size() - 1){
					BankAccountInfoVO subtotal = new BankAccountInfoVO();
					subtotal.setTopGroupName("小计：" + subtotalCount);
					subtotal.setBalance(subtotalBalance);
					results.add(subtotal);
				}
			}
			BankAccountInfoVO end = new BankAccountInfoVO();
			end.setTopGroupName("合计：" + totalCount);
			end.setBalance(totalBalance);
			results.add(end);
		}

		ReportReturnVO reportReturnVO = new ReportReturnVO();

		ReportVO reportVO = new ReportVO();

		reportVO
				.addHeader(HeaderVO.builder().key("topGroupName").title("所属集团").build())
				.addHeader(HeaderVO.builder().key("bankAccount").title("账户号").build())
				.addHeader(HeaderVO.builder().key("bankAccountName").title("账户名称").build())
				.addHeader(HeaderVO.builder().key("bankName").title("银行名称").build())
				.addHeader(HeaderVO.builder().key("openBankName").title("开户银行名称").build())
				.addHeader(HeaderVO.builder().key("accountTypeName").title("账户性质").build())
				.addHeader(HeaderVO.builder().key("accountUseName").title("账户用途").build())
				.addHeader(HeaderVO.builder().key("currentName").title("币种").build())
				.addHeader(HeaderVO.builder().key("balance").title("余额").build())
				.addHeader(HeaderVO.builder().key("rateType").title("利率类型").build())
				.addHeader(HeaderVO.builder().key("rate").title("利率").build())
				.addHeader(HeaderVO.builder().key("infiniteAgreementRate").title("无限协议利率").build())
				.addHeader(HeaderVO.builder().key("limitedAgreementAmount").title("有限协议金额").build())
				.addHeader(HeaderVO.builder().key("limitedAgreementRate").title("有限协议利率").build())
				.addHeader(HeaderVO.builder().key("accountStatusName").title("账户状态").build())
				.addHeader(HeaderVO.builder().key("openDate").title("开户日期").build())
				.addHeader(HeaderVO.builder().key("closeDate").title("销户日期").build());
		reportVO.setData(results);
		reportReturnVO.setGrids(reportVO);
		return reportReturnVO;
	}


	@Override
	public List<BankAccountInfoVO> warn() {
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes();
		String orgId = "";
		if (requestAttributes == null){
			 orgId = "101a8263ca8f0bfef57c6bb2e8937adc";
		}else {
			 orgId = TokenUtil.getTokenOrgId();
		}
		List<String> allOrgIds = null;
		try {
			allOrgIds = orgzationService.getAllChildIds(orgId);
			if (CollectionUtils.isNotEmpty(allOrgIds)) {
				List<BankAccountInfoVO> allAccountNumberByOrgId = bankAccountInfoMapper.getAllAccountNumberByOrgId(allOrgIds);
				List<BankAccountInfoVO> specialAccountNumberByOrgId = bankAccountInfoMapper.getSpecialAccountNumberByOrgId(allOrgIds);
				List<BankAccountInfoVO> accountNumberByOrgId = bankAccountInfoMapper.getAccountNumberByOrgId(allOrgIds);
				if (CollectionUtils.isNotEmpty(allAccountNumberByOrgId)) {
					for (BankAccountInfoVO bankAccountInfoVO : allAccountNumberByOrgId) {
						if (CollectionUtils.isNotEmpty(specialAccountNumberByOrgId)) {
							for (BankAccountInfoVO accountInfoVO : specialAccountNumberByOrgId) {
								if (accountInfoVO.getOrgId().equals(bankAccountInfoVO.getOrgId())) {
									bankAccountInfoVO.setSpecialAccountNumber(accountInfoVO.getSpecialAccountNumber());
								}
							}
						}
					}
				}
				if (CollectionUtils.isNotEmpty(allAccountNumberByOrgId)) {
					for (BankAccountInfoVO bankAccountInfoVO : allAccountNumberByOrgId) {
						if (CollectionUtils.isNotEmpty(accountNumberByOrgId)) {
							for (BankAccountInfoVO accountInfoVO : accountNumberByOrgId) {
								if (accountInfoVO.getOrgId().equals(bankAccountInfoVO.getOrgId())) {
									bankAccountInfoVO.setAccountNumbers(accountInfoVO.getAccountNumbers());
								}
							}
						}
					}
				}
				//排序
				Collections.sort(allAccountNumberByOrgId, (BankAccountInfoVO a, BankAccountInfoVO b) -> Integer.valueOf(b.getAccountNumbers()).compareTo(Integer.valueOf(a.getAccountNumbers())));
				return allAccountNumberByOrgId;
			}
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return null;
	}
//
//	@Override
//	public List<BankAccountInfoVO> timeoutWarning() {
//		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
//				.getRequestAttributes();
//		String orgId = "";
//		if (requestAttributes == null){
//			orgId = "101a8263ca8f0bfef57c6bb2e8937adc";
//		}else {
//			orgId = TokenUtil.getTokenOrgId();
//		}
//		List<String> allOrgIds = orgzationService.getAllChildIds(orgId);
//		if (CollectionUtils.isNotEmpty(allOrgIds)) {
//			List<BankAccountInfoVO> account = bankAccountInfoMapper.account(allOrgIds);
//			ArrayList<String> bankAccounts = new ArrayList<>();
//			if (CollectionUtils.isNotEmpty(account)) {
//				for (BankAccountInfoVO bankAccountInfoVO : account) {
//					bankAccounts.add(bankAccountInfoVO.getBankAccount());
//				}
//			}
//
//			List<BankDepositVO> deposit = bankAccountInfoMapper.deposit(bankAccounts);
//			if (CollectionUtils.isNotEmpty(deposit)) {
//				for (BankDepositVO bankDepositVO : deposit) {
//					if (CollectionUtils.isNotEmpty(account)) {
//						for (BankAccountInfoVO accountInfoVO : account) {
//							if (bankDepositVO.getBankAccount().equals(accountInfoVO.getBankAccount())) {
//								accountInfoVO.setTopGroupName(bankDepositVO.getTopGroupName());
//								accountInfoVO.setOrgName(bankDepositVO.getOrgName());
//								accountInfoVO.setOpenBankName(bankDepositVO.getOpenBankName());
//								accountInfoVO.setBankAccountName(bankDepositVO.getBankAccountName());
//								accountInfoVO.setOrgId(bankDepositVO.getOrgId());
//							}
//						}
//					}
//				}
//			}
//
//			List<BankAccountInfoVO> bankAccountInfoVOS = bankAccountInfoMapper.accountInfo(bankAccounts);
//			Map<String, String> currencyMap = baseInfoService.getChildMap(ValueSetConstant.CURRENCY);
//			if (CollectionUtils.isNotEmpty(bankAccountInfoVOS)) {
//				for (BankAccountInfoVO bankAccountInfoVO : bankAccountInfoVOS) {
//					if (CollectionUtils.isNotEmpty(account)) {
//						for (BankAccountInfoVO accountInfoVO : account) {
//							if (bankAccountInfoVO.getBankAccount().equals(accountInfoVO.getBankAccount())) {
//								accountInfoVO.setTopGroupName(bankAccountInfoVO.getTopGroupName());
//								accountInfoVO.setOrgName(bankAccountInfoVO.getOrgName());
//								accountInfoVO.setBankAccountName(bankAccountInfoVO.getBankAccountName());
//								accountInfoVO.setOpenBankName(bankAccountInfoVO.getOpenBankName());
//								accountInfoVO.setAccountTypeName(getAccountTypeName(bankAccountInfoVO.getAccountType()));
//								accountInfoVO.setAccountUseName(getAccountUseName(bankAccountInfoVO.getAccountUse()));
//								accountInfoVO.setAccountStatusName(getAccountStatusName(bankAccountInfoVO.getAccountStatus()));
//								accountInfoVO.setOpenDate(bankAccountInfoVO.getOpenDate());
//								accountInfoVO.setCurrentName(currencyMap.get(bankAccountInfoVO.getCurrentCode()));
//								accountInfoVO.setOrgId(bankAccountInfoVO.getOrgId());
//							}
//						}
//					}
//				}
//			}
//			//排序
//			Collections.sort(account, (BankAccountInfoVO a, BankAccountInfoVO b) -> b.getBalance().compareTo(a.getBalance()));
//			return account;
//		}
//		return null;
//	}
//
//
	/**
	 * 账户状态
	 * @param accountStatus
	 * @return
	 */
	private String getAccountStatusName(Integer accountStatus){
		if(Optional.ofNullable(accountStatus).isPresent()){
			switch (accountStatus){
				case 1:
					return "正常";
				case 2:
					return "保留";
				case 3:
					return "拟撤销";
				case 4:
					return "注销";
				default:
					return "";
			}
		}
		return "";
	}

	/**
	 * 账户类型
	 * @param accountType
	 * @return
	 */
	private String getAccountTypeName(Integer accountType){
		if(Optional.ofNullable(accountType).isPresent()){
			switch (accountType){
				case 1:
					return "基本户";
				case 2:
					return "一般户";
				case 5:
					return "临时户";
				case 6:
					return "专用户";
				default:
					return "";
			}
		}
		return "";
	}

	/**
	 * 账户用途
	 * @param accountUse
	 * @return
	 */
	private String getAccountUseName(Integer accountUse){
		if(Optional.ofNullable(accountUse).isPresent()){
			String accountUseBinary = Integer.toBinaryString(accountUse);
			if(StringUtil.isNotBlank(accountUseBinary)){
				StringBuilder result = new StringBuilder();
				int count = 1;
				for (int i = accountUseBinary.length() - 1; i >= 0; i--){
					char ch = accountUseBinary.charAt(i);
					int key = Integer.parseInt(String.valueOf(ch));

					if(key == 1){
						if (result.length() != 0) {
							result.insert(0, ",");
						}
						switch (count){
							case 1:
								result.insert(0, "专用");
								break;
							case 2:
								result.insert(0, "融资");
								break;
							case 3:
								result.insert(0, "大额资金存放");
								break;
							case 4:
								result.insert(0, "结算");
								break;
							default:
								break;
						}
					}
					count++;

				}
				return result.toString();
			}

		}
		return "";
	}
}
